package cn.shoukaiseki.sjf4j.log;

import cn.shoukaiseki.sjf4j.TestUtils;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;

import java.util.Iterator;
import java.util.function.BiConsumer;

public class JacksonLog extends BaseLog<JsonNode>{


    @Override
    public void printNodeInfo(String key, JsonNode jsonNode){
        sb.append("key="+key);
        if(!TestUtils.compareSwitch){ sb.append(",getClass="+jsonNode.getClass()); }
        sb.append(",isMissingNode="+jsonNode.isMissingNode());
        sb.append(",isTextual="+jsonNode.isTextual());
        sb.append(",isNull="+jsonNode.isNull());
        sb.append(",asInt="+jsonNode.asInt());
        sb.append(",asIntVal="+(jsonNode.isNull()?null:jsonNode.asInt()));
        sb.append("\n\t\t");
        sb.append(",asLong="+jsonNode.asLong());
        sb.append(",asLongVal="+(jsonNode.isNull()?null:jsonNode.asLong()));
        sb.append(",asDouble="+jsonNode.asDouble());
        sb.append(",asDoubleVal="+(jsonNode.isNull()?null:jsonNode.asDouble()));
        sb.append(",asBoolean="+(jsonNode.asBoolean()));
        sb.append(",asBooleanVal="+(jsonNode.isNull()?null:jsonNode.asBoolean()));
        sb.append("\n\t\t");
//        sb.append(",asDecimalVal="+(jsonNode.decimalValue()));
        sb.append("\n\t\t");
        sb.append(",getNodeType="+jsonNode.getNodeType());
        String numberType;
        if (jsonNode.isNumber()&&(jsonNode.numberType()== JsonParser.NumberType.DOUBLE||jsonNode.numberType()== JsonParser.NumberType.BIG_DECIMAL)) {
            numberType="DOUBLE/BIG_DECIMAL";
        }else{
            numberType=""+jsonNode.numberType();
        }
        sb.append(",numberType="+numberType);
        if (jsonNode.isTextual()) {
            sb.append(",toString=" + jsonNode.textValue());
        }else if(jsonNode.isNumber()&&(jsonNode.numberType()== JsonParser.NumberType.DOUBLE||jsonNode.numberType()== JsonParser.NumberType.BIG_DECIMAL)){
            sb.append(",toString=" + jsonNode.decimalValue());
        }else{
            sb.append(",toString="+jsonNode.toString());
        }
        sb.append("\n");
    }


    public void treeNodeTraversal(String key, JsonNode node){
        treeNodeTraversal(key,node,this::printNodeInfo);
    }

    public void treeNodeTraversal(String key, JsonNode node, BiConsumer<String,JsonNode> fun){
        if(key!=null&&node.isValueNode()||node.isNull()||node.isMissingNode()){
            fun.accept(key,node);
        }
        if (node.isObject()) {

            Iterator<String> fieldNames = node.fieldNames();
            fieldNames=sort(fieldNames);
            while (fieldNames.hasNext()) {
                String fieldName = fieldNames.next();
                JsonNode treeNode = node.get(fieldName);
                treeNodeTraversal(keyJoin(key,fieldName),treeNode,fun);
            }
        }
        if(node.isArray()){
            for (int i = 0; i <node.size(); i++) {
                JsonNode treeNode = node.get(i);
                treeNodeTraversal(keyJoin(key,i),treeNode,fun);
            }
        }
    }

}
